/*******************************************************************************
* Project name:
           PWM ratio on LCD[John]
--------------------------------------------------------------------------------
* Author:
       Dujany J., 2010, dujaj@hotmail.com
--------------------------------------------------------------------------------
* Revision History:
     18.05.2010:
       - initial release;
--------------------------------------------------------------------------------
* Description:
     This is a simple demonstration of PWM library, which is being used for
     control of the PIC's CCP module. The module is initialized and started,
     after which the PWM1 and PWM2 Duty Ratios can be adjusted by means of 4 buttons
     connected to pins RA0, RA1, RA2 and RA3. The changes can be monitored on the CCP
     output pins (RC1 and RC2) and on the small DC motors.

     This is a simple demonstration of Lcd 4-bit library functions too.
     We will display the duty ratio value that is between 0 to 255.
--------------------------------------------------------------------------------
* Test configuration:
     MCU:             PIC16F887
     Dev.Board:       EasyPIC6
     Oscillator:      HS, 8.0000 MHz
     Ext. Modules:    Mikroe Drive, DC motors
     Compiler:        MikroC PRO for PIC, v 3.2
--------------------------------------------------------------------------------
* NOTES:
     - Pull-down PORTA and connect button jumper (J17) to Vcc.
     - Turn on LEDs on PORTC SW9.3.
     - Turn OFF all others SW
*******************************************************************************/
 unsigned short current_duty, current_duty1;
 unsigned char ch;
 char *text;
 char *pwm;

 // LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections

void DisplayValue(unsigned short s) {
  ch = s/100;                           // extract hundreds digit
  LCD_Chr(2,1,48+ch);                   // write ASCII digit at 2nd row, 9th column
  ch = (s / 10)% 10;                    // extract tens digit
  LCD_Chr_CP(48+ch);                    // write ASCII digit at cursor point
  ch = s % 10;                          // extract ones digit
  LCD_Chr_CP(48+ch);                    // write ASCII digit at cursor point
  text = "/255 on PWM";                 // assign text to string
  LCD_Out(2,4,text);                    // print string a on LCD, 2nd row, 4rd column
  LCD_Out(2,15,pwm);                    // indicate on which PWM bit we look
}
void InitMain() {
  ANSEL  = 0;                         // Configure AN pins as digital
  ANSELH = 0;
  C1ON_bit = 0;                       // Disable comparators
  C2ON_bit = 0;
  PORTA = 255;                        // Configure PORTA pins as input
  TRISA = 255;
  PORTB = 0;                          // Set PORTB to 0
  TRISB = 0;                          // Designate PORTB pins as output
  PORTC = 0;                          // Set PORTC to 0
  TRISC = 0;                          // Designate PORTC pins as output
  PWM1_Init(5000);                    // Initialize PWM1 module at 5KHz
  PWM2_Init(5000);                    // Initialize PWM2 module at 5KHz

  Lcd_Init();
  LCD_Cmd(_LCD_CURSOR_OFF);           // send command to LCD (cursor off)
  LCD_Cmd(_LCD_CLEAR);                // send command  to LCD (clear LCD)
}

void main() {
  InitMain();

  Delay_1sec();
  Delay_1sec();
  current_duty  = 16;                       // Initial value for current_duty
  current_duty1 = 16;                       // Initial value for current_duty1

  PWM1_Start();                             // Start PWM1
  PWM2_Start();                             // Start PWM2
  PWM1_Set_Duty(current_duty);              // Set current duty for PWM1
  PWM2_Set_Duty(current_duty1);             // Set current duty for PWM2
  text = "mikroElektronika";                // assign text to string
  LCD_Out(1,1,text);                        // print string a on LCD, 1st row, 1st column
  text = "PWM ratio on LCD";                // assign text to string ( name of prog.)
  LCD_Out(2,1,text);                        // print string a on LCD, 2nd row, 1st column
  Delay_ms(2000);
  LCD_Cmd(_LCD_CLEAR);                      // send command  to LCD (clear LCD)
  
  while (1) {                               // Endless loop
        text = "duty ratio is:";            // assign text to string
        LCD_Out(1,1,text);                  // print string a on LCD, 1st row, 1st column

    if (RA0_bit) {                          // Button on RA0 pressed
      Delay_ms(40);
      pwm ="1";                             // Indicate on which PWM channel we look at
      current_duty++;                       // Increment current_duty
      DisplayValue(current_duty);
      PWM1_Set_Duty(current_duty);
     }

    if (RA1_bit) {                          // Button on RA1 pressed
      Delay_ms(40);
      pwm ="1";                             // Indicate on which PWM channel we look at
      current_duty--;                       // Decrement current_duty
      DisplayValue(current_duty);
      PWM1_Set_Duty(current_duty);
     }

    if (RA2_bit) {                          // Button on RA2 pressed
      Delay_ms(40);
      pwm ="2";                             // Indicate on which PWM channel we look at
      current_duty1++;                      // Increment current_duty1
      DisplayValue(current_duty1);
      PWM2_Set_Duty(current_duty1);
     }

    if (RA3_bit) {                          // Button on RA3 pressed
      Delay_ms(40);
      pwm ="2";                             // Indicate on which PWM channel we look at
      current_duty1--;                      // Decrement current_duty1
      DisplayValue(current_duty1);
      PWM2_Set_Duty(current_duty1);
     }

    Delay_ms(5);                            // Slow down change pace a little
  }
}
